package com.zxy.supplier_system.server.service

import com.zxy.supplier_system.server.controller.MarketShoppingGuideSalaryPlanController
import com.zxy.supplier_system.server.controller.MarketShoppingGuideSalaryPlanController.ConfigureMarketShoppingGuideSalaryPlanResponse
import com.zxy.supplier_system.server.entity.MarketShoppingGuideSalaryPlan
import com.zxy.supplier_system.server.entity.MarketShoppingGuideSalaryRule
import com.zxy.supplier_system.server.entity.toIntIdAndName
import com.zxy.supplier_system.server.repository.MarketRepository
import com.zxy.supplier_system.server.repository.MarketShoppingGuideSalaryPlanRepository
import com.zxy.supplier_system.server.utils.orElse404
import com.zxy.supplier_system.server.utils.toIntIdAndName
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

@Service
class MarketShoppingGuideSalaryPlanService(
    private val marketShoppingGuideSalaryPlanRepository: MarketShoppingGuideSalaryPlanRepository,
    private val systemServiceService: SystemServiceService,
    private val marketRepository: MarketRepository,
    private val employeeOperateRecordService: EmployeeOperateRecordService,
    private val goodsMatchRuleService: GoodsMatcherRuleService,
) {

    @Transactional
    fun configurePlan(
        marketId: Int,
        request: MarketShoppingGuideSalaryPlanController.ConfigureMarketShoppingGuideSalaryPlanRequest
    ): ConfigureMarketShoppingGuideSalaryPlanResponse {

        val systemService = systemServiceService.getCurrentSystemService()
        val plan = marketShoppingGuideSalaryPlanRepository.save(MarketShoppingGuideSalaryPlan().apply {
            this.market =
                marketRepository.findByIdAndSystemService(marketId, systemService)
                    .orElse404()
            this.minimumSalary = request.minimumSalary
        })
        if (request.rules.isNotEmpty()) {
            request.rules.forEach { rule ->
                plan.rules.add(MarketShoppingGuideSalaryRule().apply {
                    this.plan = plan
                    this.name = rule.name
                    this.note = rule.note
                    this.commissionPercentage = rule.commissionPercentage
                    this.fixedSalary = rule.fixedSalary
                    this.inMinimum = rule.inMinimum
                    goodsMatchRuleService.configureByRequest(goodsMatcherRule, rule)
                })
            }
            this.marketShoppingGuideSalaryPlanRepository.save(plan)
        }
        this.employeeOperateRecordService.configureMarketShoppingGuideSalaryPlan(plan)
        return planToResponse(plan)
    }

    private fun planToResponse(plan: MarketShoppingGuideSalaryPlan): ConfigureMarketShoppingGuideSalaryPlanResponse {
        return ConfigureMarketShoppingGuideSalaryPlanResponse(plan.minimumSalary, plan.rules.map {
            ConfigureMarketShoppingGuideSalaryPlanResponse.Rule(
                it.id!!, it.name, it.note, it.commissionPercentage, it.fixedSalary,
                it.inMinimum,
                it.goodsMatcherRule.includedBrands.map { brand -> brand.toIntIdAndName() },
                it.goodsMatcherRule.includedCategories.map { it.toIntIdAndName() },
                it.goodsMatcherRule.includedBrandTags.map { it.toIntIdAndName() },
                it.goodsMatcherRule.includedGoodsList.map {
                    ConfigureMarketShoppingGuideSalaryPlanResponse.Rule.GoodsItem(
                        it.id,
                        it.name,
                        it.barcode
                    )
                },
            )
        })
    }

    @Transactional(readOnly = true)
    fun getPlanResponse(marketId: Int): ConfigureMarketShoppingGuideSalaryPlanResponse? {
        val plan = this.marketShoppingGuideSalaryPlanRepository.findByMarketIdAndMarket_SystemService(
            marketId,
            systemServiceService.getCurrentSystemService()
        )
        return plan?.let { planToResponse(it) }
    }

    /**
     * 删除已有的方案，重新保存新的
     */
    @Transactional
    fun reconfigurePlan(
        marketId: Int,
        request: MarketShoppingGuideSalaryPlanController.ConfigureMarketShoppingGuideSalaryPlanRequest
    ): ConfigureMarketShoppingGuideSalaryPlanResponse {
        this.marketShoppingGuideSalaryPlanRepository.deleteByMarketIdAndMarket_SystemService(
            marketId,
            systemServiceService.getCurrentSystemService()
        )

        return this.configurePlan(marketId, request)
    }


}
